﻿using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace SimpleTaskSystem
{
    [CustomPropertyDrawer(typeof(Task))]
    public class TaskInspector : PropertyDrawer
    {
        private Dictionary<int, ReorderableList> lists = new Dictionary<int, ReorderableList>();


        private ReorderableList GetReorderableList(SerializedProperty serializedProperty)
        {
            ReorderableList list = GetReorderableList(serializedProperty, GetListId(serializedProperty));
            
            return list;
        }

        void SetReorderableList(ReorderableList list,SerializedProperty serializedProperty)
        {
            list.drawElementCallback = delegate (Rect rect, int index, bool selected, bool focused)
            {
                //绘制分割线
                Rect lineRect = rect;
                lineRect.x -= 18;
                lineRect.width += 22;
                lineRect.height = 2;
                Color c = new Color(.6f, .49f, .05f, 1f);
                EditorGUI.DrawRect(lineRect, c);


                //绘制内容
                var element = list.serializedProperty.GetArrayElementAtIndex(index);
                if (serializedProperty.isExpanded)
                {
                    rect.y += 4;
                    float currenH = rect.y + EditorGUIUtility.singleLineHeight + 4;
                    EditorGUI.PropertyField(new Rect(rect.x, currenH, rect.width, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("operationName"), new GUIContent("操作名："));
                    currenH += EditorGUIUtility.singleLineHeight;
                    EditorGUI.PropertyField(new Rect(rect.x, currenH, rect.width, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("isAutomatic"), new GUIContent("是否为自动执行"));
                    currenH += EditorGUIUtility.singleLineHeight;
                    EditorGUI.PropertyField(new Rect(rect.x, currenH, rect.width, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("description"), new GUIContent("操作描述"));
                    currenH += EditorGUIUtility.singleLineHeight;
                    EditorGUI.PropertyField(new Rect(rect.x, currenH, rect.width, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("indicate"), new GUIContent("操作提示"));
                    currenH += EditorGUIUtility.singleLineHeight;
                    float rh = new UnityEventDrawer().GetPropertyHeight(element.FindPropertyRelative("onReadyAction"), new GUIContent("准备"));
                    EditorGUI.PropertyField(new Rect(rect.x, currenH, rect.width, rh), element.FindPropertyRelative("onReadyAction"), new GUIContent("操作前准备"));
                    currenH += rh;
                    float ah = new UnityEventDrawer().GetPropertyHeight(element.FindPropertyRelative("action"), new GUIContent("操作"));
                    EditorGUI.PropertyField(new Rect(rect.x, currenH, rect.width, ah), element.FindPropertyRelative("action"), new GUIContent("操作"));
                }

                //绘制标题
                GUIStyle gs = new GUIStyle();
                c.r += 0.2f;
                c.g += 0.16f;
                gs.normal.textColor = c;
                gs.fontSize = 15;
                gs.fontStyle = FontStyle.Bold;
                EditorGUI.LabelField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight + 4), index + "、" + element.FindPropertyRelative("operationName").stringValue, gs);
            };
            list.elementHeightCallback = delegate (int index)
            {
                if (serializedProperty.isExpanded)
                {
                    var element = list.serializedProperty.GetArrayElementAtIndex(index);

                    float h = 0;
                    h += new UnityEventDrawer().GetPropertyHeight(element.FindPropertyRelative("onReadyAction"), new GUIContent("准备"));
                    h += new UnityEventDrawer().GetPropertyHeight(element.FindPropertyRelative("action"), new GUIContent("执行"));

                    return h + 8 + EditorGUIUtility.singleLineHeight * 5;
                }
                else
                {
                    return list.headerHeight;
                }
            };
            list.drawHeaderCallback = (Rect rect) =>
            {
                Rect r = rect;
                r.x += 10;
                bool show = serializedProperty.isExpanded;
                show = EditorGUI.Foldout(r, show, "操作列表");
                serializedProperty.isExpanded = show;
                //GUI.Label(rect, "操作列表");
            };
        }

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), property.FindPropertyRelative("taskName"), new GUIContent("任务名"));
            EditorGUI.PropertyField(new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight, position.width, EditorGUIUtility.singleLineHeight), property.FindPropertyRelative("isAutomatic"), new GUIContent("是否自动执行"));
            EditorGUI.PropertyField(new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight * 2, position.width, EditorGUIUtility.singleLineHeight), property.FindPropertyRelative("sequence"), new GUIContent("是否按顺序执行"));
            EditorGUI.PropertyField(new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight * 3, position.width, EditorGUIUtility.singleLineHeight), property.FindPropertyRelative("description"), new GUIContent("任务描述"));
            GetReorderableList(property).DoList(new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight * 4, position.width, EditorGUIUtility.singleLineHeight));
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            ReorderableList list = GetReorderableList(property);
            float h = list.GetHeight() + EditorGUIUtility.singleLineHeight * 6;
            return h;
        }

        public ReorderableList GetReorderableList(SerializedProperty property, int id)
        {

            if (property == null)
            {

                return null;
            }

            ReorderableList list = null;
            SerializedProperty array = property.FindPropertyRelative("operations");

            if (array != null && array.isArray)
            {

                if (!lists.TryGetValue(id, out list))
                {

                    list = new ReorderableList(property.serializedObject, array, true, true, true, true);

                    lists.Add(id, list);
                    SetReorderableList(list, property);
                }
                else
                {
                    List<SerializedProperty> l = new List<SerializedProperty>();
                    for (int i = 0; i < array.arraySize; i++)
                    {
                        l.Add(array.GetArrayElementAtIndex(i));
                    }
                    list.list = l;
                }
            }
            return list;
        }
        public int GetListId(SerializedProperty property)
        {

            if (property != null)
            {

                int h1 = property.serializedObject.targetObject.GetHashCode();
                int h2 = property.propertyPath.GetHashCode();

                return (((h1 << 5) + h1) ^ h2);
            }
            return 0;
        }

    }
}
